package com.one.group.AiUtils;

import com.mybatisflex.core.query.QueryWrapper;
import com.one.group.model.dto.VisitorAiQueryDto;
import com.one.group.model.entity.SpCell;
import com.one.group.model.entity.Visitor;
import com.one.group.service.SpCellService;
import com.one.group.service.VisitorService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * {@code @Create:}  2025-10-15  18 : 28
 * {@code @Author:} Cherry
 * {@code @ToAuthor:} 凡是发生,皆有利于我。
 * ------------------------------------
 * {@code @note:}
 */

@SuppressWarnings({"all"})
@Component
public class AITools {
    @DubboReference
    private SpCellService spCellService;
    @DubboReference
    private VisitorService visitorService;

    @Tool(description = "查询所有的小区信息地址等")
    public List<SpCell> searchBuildingList() {
        return spCellService.list();
    }

    @Tool(description = "根据查询条件查询访客信息")
    public List<Visitor> searchVisitorList(@ToolParam(description = "查询条件") VisitorAiQueryDto visitorAiQueryDto) {
        QueryWrapper wrapper = new QueryWrapper();

        // 姓名查询条件
        if (visitorAiQueryDto.getName() != null && !visitorAiQueryDto.getName().isEmpty()) {
            wrapper.like(Visitor::getName, visitorAiQueryDto.getName());
        }

        // 小区地址查询条件
        if (visitorAiQueryDto.getAddress() != null && !visitorAiQueryDto.getAddress().isEmpty()) {
            wrapper.like(SpCell::getAddress, visitorAiQueryDto.getAddress());
        }
        // 时间查询条件处理
        // 如果只提供了startTime，表示查询某一天到访的访客
        if (visitorAiQueryDto.getStartTime() != null && visitorAiQueryDto.getEndTime() == null) {
            Date startOfDay = getStartOfDay(visitorAiQueryDto.getStartTime());
            Date endOfDay = getEndOfDay(visitorAiQueryDto.getStartTime());
            wrapper.between(Visitor::getCreateTime, startOfDay, endOfDay);
        }
        // 如果只提供了endTime，表示查询在某时间之前离开的访客
        else if (visitorAiQueryDto.getStartTime() == null && visitorAiQueryDto.getEndTime() != null) {
            wrapper.le(Visitor::getUpdateTime, visitorAiQueryDto.getEndTime());
        }
        // 如果同时提供了startTime和endTime
        else if (visitorAiQueryDto.getStartTime() != null && visitorAiQueryDto.getEndTime() != null) {
            // 如果startTime和endTime是同一天，查询这一天到访的访客
            if (isSameDay(visitorAiQueryDto.getStartTime(), visitorAiQueryDto.getEndTime())) {
                Date startOfDay = getStartOfDay(visitorAiQueryDto.getStartTime());
                Date endOfDay = getEndOfDay(visitorAiQueryDto.getStartTime());
                wrapper.between(Visitor::getCreateTime, startOfDay, endOfDay);
            } else {
                // 如果是不同的日期，则查询在时间范围内的访客
                wrapper.between(Visitor::getCreateTime, visitorAiQueryDto.getStartTime(), visitorAiQueryDto.getEndTime());
            }
        }

        return visitorService.list(wrapper);
    }

    /**
     * 获取指定日期的开始时间（00:00:00）
     */
    private Date getStartOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取指定日期的结束时间（23:59:59）
     */
    private Date getEndOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 判断两个日期是否为同一天
     */
    private boolean isSameDay(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
    }
}
